package indi.mozping.synchronizedp.biasedlock;

import org.openjdk.jol.info.ClassLayout;

import java.util.ArrayList;
import java.util.List;

/**
 * @author by mozping
 * @Classname Test1
 * @Description 测试重偏向
 * -XX:BiasedLockingStartupDelay=0  -XX:+PrintFlagsFinal
 * @Date 2020/1/14 20:37
 */
public class Test1 {

    final int SIZE = 30;

    public static void main(String[] args) throws Exception {

        //创造30个锁对象
        List<LockObject> listA = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            LockObject a = new LockObject();
            System.out.println("Init state ,The " + (i + 1) + "th object head");
            System.out.println((ClassLayout.parseInstance(a).toPrintable()));
        }

        //延时产生可偏向对象,实际上设置了-XX:BiasedLockingStartupDelay=0后，立即就会启动偏向锁机制
        Thread.sleep(1000);

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 30; i++) {
                LockObject a = new LockObject();
                synchronized (a) {
                    listA.add(a);
                }
            }
            try {
                //为了防止JVM线程复用，在创建完对象后，保持线程t1状态为存活
                Thread.sleep(100000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();

        System.out.println("Thread 1 id :" + t1.getId());

        //睡眠3s钟保证线程t1创建对象完成
        Thread.sleep(3000);
        for (int i = 0; i < 30; i++) {
            LockObject a = listA.get(i);
            //打印偏向锁重偏向结果
            System.out.println("Thread t1 ,The " + (i + 1) + "th object head");
            System.out.println((ClassLayout.parseInstance(a).toPrintable()));
        }

        System.out.println("=====================================");

        //创建线程t2竞争线程t1中已经退出同步块的锁
        Thread t2 = new Thread(() -> {
            //这里面只循环了30次！！！
            for (int i = 0; i < 30; i++) {
                LockObject a = listA.get(i);
                synchronized (a) {
                    //打印偏向锁重偏向结果
                    System.out.println("Thread t2 ,The " + (i + 1) + "th biased result");
                    System.out.println((ClassLayout.parseInstance(a).toPrintable()));
                }
            }
            try {
                Thread.sleep(10000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t2.start();

        System.out.println("Thread 2 id :" + t2.getId());
        Thread.sleep(3000);
    }
}